#ifndef STM32_UART_H
#define STM32_UART_H

#include <stdio.h>
#include "gpio.h"
#include "usart.h"
#include "TypeDefine.h"

#define DEBUG_USART &huart5  //调试串口
#define UART_PORT_NUM   5  //STM32串口数量
#define UART_CONFIG_MAGIC  0x1234ABCD //串口配置校验码



//串口波特率14种
typedef enum
{
    BAUD_600 = 0x1u,
    BAUD_1200 = 0x2u,
    BAUD_2400 = 0x3u,
    BAUD_4800 = 0x4u,
    BAUD_9600 = 0x5u,
    BaUD_14400 = 0x6u,
    BAUD_19200 = 0x7u,
    BAUD_38400 = 0x8u,
    BAUD_57600 = 0x9u,
    BAUD_115200 = 0xAu,
    BAUD_230400 = 0xBu,
    BAUD_345600 = 0xCu,
    BAUD_460800 = 0xDu,
    BAUD_921600 = 0xEu,
} UartBaudRateEnum;
static inline uint32_t GetBaudrateValue(UartBaudRateEnum eBaud)
{
    switch(eBaud)
    {   
        case BAUD_600:     return 600;
        case BAUD_1200:    return 1200;
        case BAUD_2400:    return 2400;
        case BAUD_4800:    return 4800;
        case BAUD_9600:    return 9600;
        case BaUD_14400:   return 14400;
        case BAUD_19200:   return 19200;
        case BAUD_38400:   return 38400;
        case BAUD_57600:   return 57600;
        case BAUD_115200:  return 115200;
        case BAUD_230400:  return 230400;
        case BAUD_345600:  return 345600;
        case BAUD_460800:  return 460800;
        case BAUD_921600:  return 921600;
        default:           return 9600;
    }
}

//串口数据位2种
typedef enum
{
    DATA_BITS_8 = 0, // UART_WORDLENGTH_8B
    DATA_BITS_9      // UART_WORDLENGTH_9B
} UartDataBitsEnum;
static inline uint32_t GetWordLengthValue(UartDataBitsEnum eBits)
{
    switch(eBits)
    {
        case DATA_BITS_8: return UART_WORDLENGTH_8B;
        case DATA_BITS_9: return UART_WORDLENGTH_9B;
        default:          return UART_WORDLENGTH_8B;
    }
}

//串口停止位2种
typedef enum
{
    STOP_BITS_1 = 0,  // UART_STOPBITS_1
    STOP_BITS_2       // UART_STOPBITS_2
} UartStopBitsEnum;

static inline uint32_t GetStopBitsValue(UartStopBitsEnum eStop)
{
    switch(eStop)
    {
        case STOP_BITS_1: return UART_STOPBITS_1;
        case STOP_BITS_2: return UART_STOPBITS_2;
        default:          return UART_STOPBITS_1;
    }
}

//串口校验方式3种
typedef enum
{
    PARITY_NONE = 0, // UART_PARITY_NONE
    PARITY_EVEN,     // UART_PARITY_EVEN
    PARITY_ODD,      // UART_PARITY_ODD
} UartParityEnum;

static inline uint32_t GetParityValue(UartParityEnum eParity)
{
    switch(eParity)
    {
        case PARITY_NONE: return UART_PARITY_NONE;
        case PARITY_EVEN: return UART_PARITY_EVEN;
        case PARITY_ODD:  return UART_PARITY_ODD;
        default:          return UART_PARITY_NONE;
    }
}


typedef struct
{
    UartBaudRateEnum BaudRate;
    UartDataBitsEnum DataBits;
    UartStopBitsEnum StopBits;
    UartParityEnum   Parity;
} UART_ConfigTypeDef;

extern const UART_ConfigTypeDef g_defaultUartConfig;  // 只声明，不定义

typedef struct {
    uint32_t magic;
    UART_ConfigTypeDef configs[UART_PORT_NUM];  // 保存5个串口配置
} UART_AllConfigs;


typedef struct _Uart_TypeDef
{
	UART_HandleTypeDef *pst_huart;       //STM32串口
    UART_ConfigTypeDef  config;          //串口参数配置
	GPIO_TypeDef       *pst_DEPort;      //RS485 DE端口
	uint32_t            ul_DEPin;        //RS485 DE引脚

	void (*TxCplCallback)(struct _Uart_TypeDef *pst_UartStruct);                     /*接收完成回调函数*/
    void (*RxCplCallback)(struct _Uart_TypeDef *pst_UartStruct, uint16_t uin_Size);  /*接收完成回调函数*/
    void (*ErrorCallback)(struct _Uart_TypeDef *pst_UartStruct);                     /*错误回调函数*/
}Uart_TypeDef;


extern Uart_TypeDef gst_Uart1;
extern Uart_TypeDef gst_Uart2;
extern Uart_TypeDef gst_Uart3;
extern Uart_TypeDef gst_Uart4;
extern Uart_TypeDef gst_Uart5;



#ifdef __cplusplus
extern "C" {
#endif

uint8_t STM32UartTransmit(Uart_TypeDef *pst_UartStruct, uint8_t *puch_Data, uint16_t uin_Size);
uint8_t STM32UartReceive(Uart_TypeDef *pst_UartStruct, uint8_t *puch_Data, uint16_t uin_MaxSize);
uint8_t STM32UartBaudRate(Uart_TypeDef *pst_UartStruct, uint32_t ul_BaudRate);
uint8_t STM32UartSetConfig(Uart_TypeDef *pst_UartStruct);
void STM32UartTxClpCallBack(Uart_TypeDef *pst_UartStruct);
void STM32UartRxClpCallBack(Uart_TypeDef *pst_UartStruct);
void Wait_Tx_Complete(void); 
	
#ifdef __cplusplus
}
#endif

#endif

